Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: TPM2 Support #4337

Merged
merged 7 commits into from
Oct 7, 2024

Conversation

atreiber94
Copy link
Collaborator

@atreiber94 atreiber94 commented Sep 6, 2024

Included in the Pull Request

This introduces an initial integration with TPM 2.0 (#3877) with the following functionality:

Class/Module Remarks
TPM2::Context Basic connection lifetime management, querying of (some) authorative information (e.g. supported algorithms), and persisting/evicting keys.
TPM2::Session TPM 2.0 session management for authorization and parameter encryption based on HMAC and (optionally) binding to a TPM-hosted keypair.
TPM2::RandomNumberGenerator Access the TPM's RNG via Botan's abstract RNG interface
TPM2::PublicKey, TPM2::PrivateKey Base classes for key pairs hosted on the TPM.
TPM2::HashFunction (Internal) adapter to use the TPM's hash functionality via Botan's abstract hash interface. Adds support for "hash-check tickets" that are needed for signing data with "restricted" keys on the TPM
tpm2_rsa Derived classes to manage and use RSA keys on the TPM. Allows signing/verification and encryption/decryption.
tpm2_crypto_backend Lets the TSS use Botan's crypto primitives (hashes, HMAC, symmetric ciphers and key exchange) for the necessary client-side crypto to communicate securely with the TPM

Also, we added documentation describing the basics of the TPM 2 wrapper.

Design Rationale

The wrapper is designed to seamlessly integrate TPM2 into Botan, i.e., one can always use the provided functionalities in Botan without detailed knowledge about the underlying TPM Software Stack (TSS). If, however, the user wants more fine-grained control, they can use the TSS directly to set up objects and then pass their handles into the Botan wrappers. For instance, a custom "policy session" could be defined that way and then passed into Botan's key pair wrappers via the introduced Botan::TPM2::Session wrapper to access a key that was configured externally. To enhance readability for these cases, the required input types from the TSS have been forward declared (as opposed to generic void*/uint32_t input types introduced in #4117 that is superceded by this PR).

Future Work

  • Expose the TPM 2 functionality via the FFI and/or python wrapper

Limitations of the TPM wrapper

The current state of the implementation covers the TPM's functionality only partially. Below is a non-exhaustive list of limitations and potential future work:

  • Support for elliptic-curve cryptography (preview: TPM2: ECC Support (won't merge here) Rohde-Schwarz/botan#14)
    • TPM2::ECC_PublicKey / TPM2::ECC_PrivateKey (in a new module tpm2_ecc)
    • ECC-based key exchange in the crypto backend callback (get_ecdh_point())
  • Configuration of key pair properties on creation (perhaps based on #4318)
    • Restrict key usage (sign vs. X.509 certification vs. verify)
    • Restrict signature schemes (e.g. signing only with PSS)
    • Duplicatability ("fixed to TPM", "fixed to parent key")
    • Usage restrictions
    • Hierarchies (currently only "Owner")
    • Primary and/or Derived Keys (currently only "Ordinary" Keys)
    • ...
  • Sessions
    • Audit sessions
    • Policy sessions
    • for existing HMAC-sessions: allow specifying a "caller nonce"
  • Verification of the TPM
    • Access/Validate the Endorsement Key and its Certificate
    • Access/Validate the platform certificate
  • Access to NVRAM
  • Symmetric Cryptography
  • Measurements/PCRs
  • Remote Attestation
    • e.g. to certify a key pair via X.509-sign

Comment on lines +71 to +82
bool not_zero_64(std::span<const uint8_t> in) {
Botan::BufferSlicer bs(in);

while(bs.remaining() > 8) {
if(Botan::load_be(bs.take<8>()) == 0) {
return false;
}
}
// Ignore remaining bytes

return true;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was an open discussion in the previous PR where Jack pointed out that this could fail randomly with a 1/2^64 probability.

@reneme reneme mentioned this pull request Sep 6, 2024
2 tasks
@coveralls
Copy link

coveralls commented Sep 6, 2024

Coverage Status

coverage: 91.014% (-0.3%) from 91.28%
when pulling 51fd5dd on Rohde-Schwarz:feature/tpm2_support
into 7f256a0 on randombit:master.

@randombit randombit self-requested a review September 6, 2024 16:05
Copy link
Owner

@randombit randombit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a complete review yet but looks quite good to me. One question is I’m a bit confused by the separation of RSA support into an optional submodule. Would TPM2 w/o RSA be a common scenario? Its hard to see what one would use it for in that setting.

src/lib/prov/tpm2/tpm2_algo_mappings.h Show resolved Hide resolved
src/lib/prov/tpm2/tpm2_algo_mappings.h Show resolved Hide resolved
using TPM2_HANDLE = uint32_t;

/// Forward declaration of TSS2 type for convenience
using ESYS_TR = uint32_t;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these need to be in the global namespace?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhh, when including the TSS headers they won't be namespaced either. As stated further below: #4337 (comment).

src/lib/prov/tpm2/tpm2_hash.h Show resolved Hide resolved
src/lib/prov/tpm2/tpm2_hash.h Outdated Show resolved Hide resolved
#include <botan/exceptn.h>

/// Forward declaration of TSS2 type for convenience
using TSS2_RC = uint32_t;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be in namespace?

Copy link
Collaborator

@reneme reneme Sep 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These forward declares and "forward typedefs" are a bit dirty anyway, as they will cause trouble if the TSS would ever change their underlying types (obviously). I'm fairly confident that they won't do that, given that this API is standardized and agreed upon by the TCG.

We chose to put them into global namespace, because they are (or will be) in global namespace in the TSS headers as well. Moving them into Botan::TPM2 would be possible, I think. No strong opinion on that, to be honest.

That said: Perhaps it would be a good idea to move all those forward declares into a dedicated header (say: tpm2_forward_declares.h).

@reneme
Copy link
Collaborator

reneme commented Sep 7, 2024

One question is I’m a bit confused by the separation of RSA support into an optional submodule.

Right now that doesn't really make sense. But once ECC keys are added, users could build with TPM support but omit RSA entirely, if they wish to do so. Or vice versa.

@reneme reneme added this to the Botan 3.6.0 milestone Sep 10, 2024
@reneme reneme added the enhancement Enhancement or new feature label Sep 10, 2024
@reneme
Copy link
Collaborator

reneme commented Oct 2, 2024

Not a complete review yet but looks quite good to me.

@randombit Thanks! I addressed your comments.

We're currently working on support for ECDSA (and ECDH for the crypto backend) -- here. We could add this here or apply it as a separate PR once this is merged. In any case, it would be great if this level of TPM2 support would make it into 3.6.0.

atreiber94 and others added 3 commits October 2, 2024 15:27
Installs swtpm on the CI build machines to simulate a TPM 2.0 chip and adds
infrastructure to pass TPM-related parameters to the unit test binary.
Also adds an empty tpm2 module that can be enabled by configuring with
./configure.py --with-tpm2

Co-Authored-By: René Meusel <[email protected]>
Namely:

  * TPM2::Context - allowing to request basic authorative information
  * TPM2::Session - to create an unauth'ed HMAC session with the TPM
  * TPM2::Error   - Botan exception encapsulation TPM-related errors
  * TPM2::Object  - handles the lifetime of TPM object handles
  * tpm2_util.h   - utility functions to handle calls to ESYS API
  * tpm2_algo_mappings.h  - mappings from Botan algo strings to TSS'
                            algorithm IDs and scheme definitions

Note, that some of those things aren't actively used in this commit, yet.

Co-Authored-By: René Meusel <[email protected]>
atreiber94 and others added 3 commits October 2, 2024 15:48
Along with the actual asymmetric algorithm support this adds a number
of required auxiliaries. Most notably, TPM2::HashFunction is an internal
class exposing the TPM's hashing functionality as a Botan::HashFunction.
'Restricted' keys must use this to obtain a token from the TPM proofing
that the data was hashed (and validated) by the TPM.

The RSA adapter is stashed into the 'tpm2_rsa' submodule so that RSA
support can be disabled at compile time. To facilitate the addition of
ECC keys, an abstract TPM2::PrivateKey class is always part of the main
TPM2 module.

Asymmetric keys can be created, loaded, persisted and evicted as needed.

Finally, asymmetric keys (on the TPM) may now be used to establish
authenticated sessions.

Co-Authored-By: René Meusel <[email protected]>
This adds an implementation of the tpm2-tss crypto callbacks. If
enabled, Botan will be used for the client-side crypto functions to
communicate with the TPM. This lets applications shed a transitive
dependency on another crypto library (like OpenSSL or mbedTLS).

The crypto callbacks are available in tpm2-tss 4.0 and later. Before
that, calling TPM2::Context::use_botan_crypto_backend() will result in
an exception.

Co-Authored-By: René Meusel <[email protected]>
@atreiber94 atreiber94 merged commit 7624371 into randombit:master Oct 7, 2024
40 checks passed
@reneme reneme deleted the feature/tpm2_support branch October 8, 2024 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Enhancement or new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants